package com.example.cc.server.service.impl;

import com.example.cc.common.enums.ConfigActionEnum;
import com.example.cc.server.exception.ConfigNotFoundException;
import com.example.cc.server.rabbitmq.ConfigEventPublisher;
import com.example.cc.server.service.ConfigurationMemoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class ConfigurationMemoryServiceImpl implements ConfigurationMemoryService {

    private final ConfigEventPublisher eventPublisher;
    private final ConcurrentHashMap<String, Object> configDataCache = new ConcurrentHashMap<>();

    @Autowired
    public ConfigurationMemoryServiceImpl(ConfigEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;

        // 初始化默认的配置数据，实际应从数据库加载
        Map<String, String> map = Map.of(
                "key1", "value101",
                "key2", "value102",
                "key3", "value103",
                "key4", "value104",
                "key5", "value105",
                "shopping.cart.max-capacity", "199",
                "shopping.cart.remove_expired", "true"
        );
        configDataCache.putAll(map);
    }

    @Override
    public Map<String, Object> getAllConfigs() {
        return Collections.unmodifiableMap(configDataCache);
    }

    @Override
    public Optional<Object> getConfigByKey(String key) {
        return Optional.ofNullable(configDataCache.get(key));
    }

    @Override
    public Object getByKey(String key) throws ConfigNotFoundException {
        if (!exists(key)) {
            throw new ConfigNotFoundException("Configuration for key " + key + " does not exist.");
        }
        return configDataCache.get(key);
    }

    @Override
    public boolean exists(String key) {
        return configDataCache.containsKey(key);
    }

    @Override
    public void create(String key, Object value) throws IllegalArgumentException {
        if (exists(key)) {
            throw new IllegalArgumentException("Configuration for key " + key + " already exists.");
        }
        if (value == null) {
            return;
        }
        configDataCache.put(key, value);
        publishEvent(key, ConfigActionEnum.CREATE, value);
        log.info("Created configuration for key: {}, value: {}", key, value);
    }

    @Override
    public void update(String key, Object value) throws IllegalArgumentException {
        if (!exists(key)) {
            throw new IllegalArgumentException("Configuration for key " + key + " does not exist.");
        }
        if (value == null) {
            return;
        }
        configDataCache.put(key, value);
        publishEvent(key, ConfigActionEnum.UPDATE, value);
        log.info("Updated configuration for key: {}, value: {}", key, value);
    }

    @Override
    public boolean delete(String key) {
        if (!exists(key)) {
            return false;
        }
        configDataCache.remove(key);
        publishEvent(key, ConfigActionEnum.DELETE, null);
        log.info("Deleted configuration for key: {}", key);
        return true;
    }

    private void publishEvent(String key, ConfigActionEnum action, Object value) {
        eventPublisher.publish(key, action, value);
    }
}
